package com.zbkj.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.zbkj.admin.service.AdminOrderHandleService;
import com.zbkj.common.constants.Constants;
import com.zbkj.common.enums.*;
import com.zbkj.common.exception.CommonException;
import com.zbkj.common.model.order.OrderDetail;
import com.zbkj.common.model.order.OrderInfo;
import com.zbkj.common.model.product.Product;
import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserBill;
import com.zbkj.common.page.CommonPage;
import com.zbkj.common.request.order.AdminOrderQueryRequest;
import com.zbkj.common.request.order.AdminOrderSaveRequest;
import com.zbkj.common.request.order.OrderApprovalRequest;
import com.zbkj.common.response.UploadResponse;
import com.zbkj.common.response.order.AdminOrderResponse;
import com.zbkj.common.response.order.OrderSucceResponse;
import com.zbkj.common.response.order.UserRechargeResponse;
import com.zbkj.common.vo.order.OrderConditionVo;
import com.zbkj.common.vo.user.UserDatavalVo;
import com.zbkj.service.service.UploadService;
import com.zbkj.service.service.order.OrderDetailService;
import com.zbkj.service.service.order.OrderInfoService;
import com.zbkj.service.service.product.ProductService;
import com.zbkj.service.service.project.ProjectInfoService;
import com.zbkj.service.service.user.UserBillService;
import com.zbkj.service.service.user.UserService;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther:
 * @Date: 2024/9/16 01:07
 * @Description:
 */
@Service
public class AdminOrderHandlerServiceImpl implements AdminOrderHandleService {

    @Autowired
    private UserService userService;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    @Lazy
    private AdminOrderHandleService adminOrderHandleService;
    @Autowired
    private UserBillService userBillService;
    @Autowired
    private ProductService productService;
    @Autowired
    private UploadService uploadService;
    @Autowired
    private ProjectInfoService projectInfoService;

    @Override
    public UserRechargeResponse getUserRechargeInfo(String phone) {
        User user = userService.getUserByAccount(phone);
        userService.userValidCheck(user);
        UserRechargeResponse response = new UserRechargeResponse();
        BeanUtils.copyProperties(user,response);
        response.setTotalDataval(user.getCardDataval()+user.getDataval());
        if(Objects.isNull(user.getCardExpire()) || user.getCardExpire().getTime() < System.currentTimeMillis()) {
            int num = orderDetailService.getValidYearProductOrderCount(user.getId());
            response.setBuyYearCardFlag(num>0?1:0);
        } else {
            response.setBuyYearCardFlag(1);
        }
        response.setSysTime(System.currentTimeMillis());
        return response;
    }

    @Override
    public PageInfo<AdminOrderResponse> list(AdminOrderQueryRequest paramRequest) {
        List<AdminOrderResponse> respList = Lists.newArrayList();
        PageInfo<OrderInfo> orderPage = orderInfoService.getAdminList(paramRequest);
        List<OrderInfo> orderList = orderPage.getList();
        if(CollectionUtils.isEmpty(orderList)) {
            return CommonPage.copyPageInfo(orderPage,respList);
        }
        List<Long> orderIdList = orderList.stream().map(k->k.getId()).collect(Collectors.toList());
        Map<Long, List<OrderDetail>> detailGroupMap = orderDetailService.getGroupOrderIdMap(orderIdList);
        for(OrderInfo orderInfo : orderList) {
            AdminOrderResponse orderResp = new AdminOrderResponse();
            BeanUtils.copyProperties(orderInfo,orderResp);
            //凭证图片url转换为显示集合
            orderResp.setPayVouchesList(orderInfoService.payVouchesStrToShowList(orderInfo.getPayVouches()));
            //订单明细-转换为订单明细响应对象
            List<OrderDetail> tempDetaiList = detailGroupMap.getOrDefault(orderInfo.getId(), Lists.newArrayList());
            orderResp.setOrderDetailList(orderDetailService.pojoToDetailResp(tempDetaiList));
            respList.add(orderResp);
        }
        return CommonPage.copyPageInfo(orderPage,respList);
    }

    @Override
    public OrderSucceResponse orderSave(AdminOrderSaveRequest saveRequest) {
        saveRequest.paramCheck();
        Date currentDate = new Date();
        User user = userService.getUserByAccount(saveRequest.getUserPhone());
        userService.userValidCheck(user);
        List<Long> productIdList = saveRequest.getOrderDetailList().stream().filter(v-> Objects.nonNull(v.getProductId())).map(v->v.getProductId()).collect(Collectors.toList());
        List<Product> dbProductList = productService.getByProductIds(productIdList, Lists.newArrayList(0));
        //订单明细参数检查及组装OrderDetail对象
        List<OrderDetail> orderDetailList = orderDetailService.saveOrderParamCheckAndPojoBuild(saveRequest.getOrderDetailList(), user, dbProductList, currentDate);
        OrderInfo orderInfo = orderInfoService.saveOrderPojoBuild(user,1);
        //将保存的图片集合-转为","分隔字符串
        String vouches = orderInfoService.payVouchesToSaveStrList(saveRequest.getPayVouchesList());
        orderInfo.setPayVouches(vouches);
        BigDecimal calcAmount = orderDetailService.calcTotalDetailFromDetail(orderDetailList);
        if(calcAmount.compareTo(saveRequest.getTotalAmount()) != 0) {
            throw new CommonException("商品购买金已变更，请刷新后重试");
        }
        orderInfo.setTotalAmount(calcAmount);
        orderInfo.setRemark(saveRequest.getRemark());
        adminOrderHandleService.orderSaveHandle(orderInfo,orderDetailList);
        //组装返回响应对象
        OrderSucceResponse succeResponse = new OrderSucceResponse();
        succeResponse.setOrderNo(orderInfo.getOrderNo());
        return succeResponse;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderSaveHandle(OrderInfo orderInfo, List<OrderDetail> orderDetailList) {
        boolean flag = orderInfoService.save(orderInfo);
        if(!flag) {
            throw new CommonException("订单保存失败");
        }
        for(OrderDetail orderDetail : orderDetailList) {
            orderDetail.setOrderId(orderInfo.getId());
        }
        //保存订单明细
        orderDetailService.saveBatch(orderDetailList);
    }

    @Override
    public void orderApproval(OrderApprovalRequest approvalRequest) {
        Long orderId = approvalRequest.getId();
        Integer status = approvalRequest.getStatus();
        OrderInfo orderInfo = orderInfoService.getOrderInfo(orderId, null);
        if(!OrderStatusEnum.isOrderStatus1(orderInfo.getOrderStatus())) {
            throw new CommonException("订单状态已变更，请刷新后重试");
        }
        if(OrderStatusEnum.isOrderStatus2(status)) {
            User user = userService.getUserById(orderInfo.getUserId());
            userService.userValidCheck(user);
            List<OrderDetail> orderDetailList = orderDetailService.getListByOrderIds(Lists.newArrayList(orderInfo.getId()));
            if(OrderTypeEnum.isType1(orderInfo.getOrderType())) {
                //申请报告订单开通处理
                adminOrderHandleService.orderStatusUpdate(orderInfo,status,Lists.newArrayList(OrderStatusEnum.ORDER_STATUS1.getStatus()), null);
            } else {
                //年卡流量包订单开通处理
                adminOrderHandleService.orderApprovalOpen(user,orderInfo,orderDetailList);
            }
        } else if(OrderStatusEnum.isOrderStatus3(status)) {
            if(StringUtils.isBlank(approvalRequest.getRejectReason())) {
                throw new CommonException("请填写拒绝原因");
            }
            //更新订单状态处理
            adminOrderHandleService.orderStatusUpdate(orderInfo,status,Lists.newArrayList(OrderStatusEnum.ORDER_STATUS1.getStatus()), approvalRequest.getRejectReason());
        } else {
            throw new CommonException("状态参数错误");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderApprovalOpen(User user, OrderInfo orderInfo, List<OrderDetail> orderDetailList) {
        Date currentDate = new Date();
        long cardDataval = 0, dataval = 0;
        Long yearCardId = null;
        int yearCardCount = 0; // 购买的年卡数量

        for (OrderDetail detail : orderDetailList) {
            if (ProductTypeEnum.isType1(detail.getProductType())) {
                yearCardId = detail.getProductId();
                cardDataval += detail.getTotalDataval().longValue();
                yearCardCount += detail.getProductNum(); // 假设每个年卡产品对应1年的时长
            }
        }

//        if(Objects.nonNull(yearCardId)) {
//            if((Objects.nonNull(user.getCardExpire()) && user.getCardExpire().getTime()>= currentDate.getTime())) {
//                throw new CommonException("该用户已拥用年卡，无法开通购买年卡订单");
//            }
//        }
        UserDatavalVo userDatavalVo = new UserDatavalVo();
        userDatavalVo.setUserId(user.getId());
        userDatavalVo.setCardDataval(cardDataval);
        userDatavalVo.setDataval(-1); // 将流量包设置为无限大（-1 可以表示无限大，具体根据业务逻辑而定）
        userDatavalVo.setYearPid(yearCardId);
        userDatavalVo.setPmtype(1);
        userDatavalVo.setCategoryEnum(UserBillCategoryEnum.BILL_CATEGORY1);
        userDatavalVo.setSourceType(1);
        userDatavalVo.setSourceId(orderInfo.getId());

        userDatavalVo.setYearCardCount(yearCardCount); // 设置年卡数量
        userDatavalVo.setCurrentDate(currentDate);     // 设置当前日期

        //组装用户账本
        List<UserBill> userBillList =  userBillService.userDataValVoToPojo(userDatavalVo);
        if(cardDataval>0 && Objects.nonNull(user.getCardExpire()) && user.getCardExpire().getTime() < currentDate.getTime()) {
            //如果当前年卡已失效，进行失效扣除处理
            userService.userCardExpireHandle(user);
        }

        //更新用户流量包信息
        boolean updateFlag = userService.incrDataval(userDatavalVo, userBillList);
        if(!updateFlag) {
            throw new CommonException("用户流量记录更新失败");
        }
        //更新订单状态处理
        this.orderStatusUpdate(orderInfo,OrderStatusEnum.ORDER_STATUS2.getStatus(),Lists.newArrayList(OrderStatusEnum.ORDER_STATUS1.getStatus()), null);
    }

    @Override
    public UploadResponse payVoucheUpload(MultipartFile multipartFile) {
        if(multipartFile == null || multipartFile.isEmpty()) {
            throw new CommonException("凭证文件不能为空");
        }
        String fileName = multipartFile.getOriginalFilename();
        String fileType = FilenameUtils.getExtension(fileName);
        UploadResponse uploadResponse = new UploadResponse();
        uploadResponse.setFileName(fileName);
        uploadResponse.setExtName(fileType);
        uploadResponse.setFileSize(multipartFile.getSize());
        try (InputStream in = multipartFile.getInputStream()){
            String fileUrl =  uploadService.inputStreamUpload(fileType, Constants.ORDER_DOC_PREFIX, in);
            uploadResponse.setUrl(fileUrl);
        } catch (CommonException ce) {
            throw ce;
        } catch (Exception ce) {
            throw new CommonException("凭证文件上传失败");
        }
        return uploadResponse;
    }

    @Transactional(rollbackFor = Exception.class)
    public void orderStatusUpdate(OrderInfo orderInfo, Integer modifyStatus, List<Integer> checkStatusList, String rejectReason) {
        if(OrderTypeEnum.isType1(orderInfo.getOrderType())) {
            //更新项目报告申请状态
            int reportStatus = OrderStatusEnum.isOrderStatus2(modifyStatus) ? ReportApplyStatusEnum.PASS_APPLY.getStatus() :ReportApplyStatusEnum.REJECT_APPLY.getStatus();
            projectInfoService.reportApplyStatusUpdate(orderInfo.getProjectId(),reportStatus);
        }
        OrderInfo updateOrder = new OrderInfo();
        updateOrder.setId(orderInfo.getId());
        updateOrder.setOrderStatus(modifyStatus);
        updateOrder.setRejectReason(rejectReason);
        OrderConditionVo conditionVo = new OrderConditionVo();
        conditionVo.setOrderStatusList(checkStatusList);
        boolean flag = orderInfoService.updateOrder(updateOrder,conditionVo);
        if(!flag) {
            throw new CommonException("订单状态已变更，请刷新后重试");
        }
    }
}
